Skip to content

src: let Environments on one isolate share a cleanup hook - #65777

Open
codebytere wants to merge 1 commit into
nodejs:mainfrom
codebytere:fix/embedder-cleanup-hook-registry
Open

src: let Environments on one isolate share a cleanup hook#65777
codebytere wants to merge 1 commit into
nodejs:mainfrom
codebytere:fix/embedder-cleanup-hook-registry

Conversation

@codebytere

@codebytere codebytere commented Sep 4, 2026

Copy link
Copy Markdown
Member

Two Environments that share an isolate and register the same cleanup hook abort the process on the second napi_add_env_cleanup_hook(), which is a normal thing for an addon loaded into several Environments to do (Electron subframes and same-process child windows share Blink's isolate). The process-global registry from #63985 is keyed on {isolate, fun, arg} and CHECKs that every insertion is unique.

The registry is now keyed on arg with the Environment carried in each entry: the same hook twice in one Environment still aborts as documented, removal prefers the current Environment's entry and falls back to a matching one, and a running hook's entry is erased by CleanupHookThunkRun() itself so a hook that removes itself (as ~ObjectWrap() does) stays safe, keeping #65630 fix intact.

Tests: EnvironmentTest.SameCleanupHookInTwoEnvironmentsOnOneIsolate (aborted before), RemoveCleanupHookOfOtherEnvironmentOnSameIsolate, CleanupHookRemovesItselfWhileRunning; test/addons, test/node-api and test/js-native-api pass.

Refs: #63985
Refs: #65630


Disclosure: the code, tests and this description were written by Claude Code, directed and reviewed by @codebytere.

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. labels Sep 4, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@codebytere
codebytere force-pushed the fix/embedder-cleanup-hook-registry branch from c16a038 to 61f728b Compare September 4, 2026 08:47
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.87097% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.16%. Comparing base (1e0ebef) to head (ed4bf45).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/api/hooks.cc 83.87% 0 Missing and 5 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #65777      +/-   ##
==========================================
- Coverage   90.17%   90.16%   -0.02%     
==========================================
  Files         771      771              
  Lines      265097   265111      +14     
  Branches    50362    50371       +9     
==========================================
- Hits       239054   239027      -27     
- Misses      17004    17014      +10     
- Partials     9039     9070      +31     
Files with missing lines Coverage Δ
src/api/hooks.cc 86.85% <83.87%> (+0.52%) ⬆️

... and 34 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@codebytere codebytere changed the title src: fix cleanup hook registry for shared isolates and self-removal src: let Environments on one isolate share a cleanup hook Sep 4, 2026
@codebytere
codebytere force-pushed the fix/embedder-cleanup-hook-registry branch from 61f728b to df3574c Compare September 4, 2026 17:19
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@codebytere codebytere added request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. and removed request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. labels Sep 5, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

The registry behind `AddEnvironmentCleanupHook()` is keyed on
{isolate, fun, arg} and asserts that every insertion is unique. Two
Environments on one isolate that register the same hook, which the
Node-API documentation allows per environment, abort the process on
the second `napi_add_env_cleanup_hook()`.

Key the registry on `arg` only and tell entries apart by Environment:
adding the same hook to one Environment twice still aborts as
documented, and removal prefers the current Environment's registration,
falling back to a matching one from another Environment when there is
no current context. Because the entry to remove after a hook has run can
no longer be found by {isolate, fun, arg} alone, `CleanupHookThunkRun()`
marks its entry as running and erases exactly that entry afterwards; a
removal of a running entry (a hook removing itself, as `~ObjectWrap()`
does) is a no-op, which keeps the use-after-free fixed by nodejs#65630 fixed.

Refs: nodejs#63985
Refs: nodejs#65630
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
@codebytere
codebytere force-pushed the fix/embedder-cleanup-hook-registry branch from df3574c to ed4bf45 Compare September 7, 2026 22:03
@codebytere codebytere added the request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. label Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants